/*************************************************************************
 * Copyright 2008 David Almilli
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 *  
 *     http://www.apache.org/licenses/LICENSE-2.0 
 *      
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 **************************************************************************/
package com.almilli.catnip.web;

import com.tivo.hme.interfaces.IContext;
import com.tivo.hme.interfaces.IFactory;
import com.tivo.hme.interfaces.ILogger;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.net.URL;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * The <code>HmeContext</code> class provides an implementation of IContext that is suitable for
 * wrapping the servlet request api.
 * @author s2kdave
 */
public class HmeContext implements IContext {
	private IFactory factory;
	private HttpServletRequest request;
	private PushbackInputStream in;
	private OutputStream out;
	private ILogger logger;
	private URL assetURI;
	private URL baseURI;

	public HmeContext(IFactory factory, HttpServletRequest request, HttpServletResponse response) 
	throws IOException {
		this.factory = factory;
		this.request = request;
		this.in = new PushbackInputStream(request.getInputStream(), 1);
		this.out = response.getOutputStream();
		
		StringBuilder sb = new StringBuilder();
		sb.append(request.getScheme()).append("://");
		sb.append(request.getServerName()).append(':');
		sb.append(request.getServerPort()).append('/');
		sb.append(request.getServletPath());
		this.baseURI = new URL(sb.toString());
	}

	public void close() throws IOException {
		if (out != null) {
			out.flush();
			out.close();
		}
		if (in != null) {
			in.close();
		}
	}

	public String getConnectionAttribute(String key) {
		return request.getParameter(key);
	}

	@SuppressWarnings("unchecked")
	public Map getConnectionAttributes() {
		return request.getParameterMap();
	}

	public PushbackInputStream getInputStream() {
		return in;
	}

	public ILogger getLogger() {
		return logger;
	}

	public OutputStream getOutputStream() {
		return out;
	}

	public String getReceiverGUID() {
		return getConnectionAttribute("tsn");
	}

	public void setLogger(ILogger logger) {
		this.logger = logger;
	}

	public void setAssetURI(URL assetURI) {
		this.assetURI = assetURI;
	}

	public URL getAssetURI() {
        if (assetURI == null) {
            synchronized (this) {
                if (assetURI == null) {
                    assetURI = factory.getAssetURI();
                    if (assetURI == null) {
                        try {
                            assetURI = new URL(baseURI, "assets/");
                        } catch (IOException e) {
                            getLogger().log(ILogger.LOG_INFO, "cannot create URL." + e.getMessage());
                        }
                    }
                }
            }
        }
        return assetURI;
	}

	public URL getBaseURI() {
		return baseURI;
	}

	public String getPersistentData(String key) {
		// TODO implement this
		return null;
	}

	public String getPersistentData(String key, String applicationId, boolean applicationGlobal) {
		// TODO implement this
		return null;
	}

	public void setPersistentData(String key, String value) {
		// TODO implement this
	}

	public void setPersistentData(String key, String value, String applicationId,
			boolean applicationGlobal) {
		// TODO implement this
	}
}
